import { 
  sendVideoOffer, 
  sendVideoAnswer, 
  sendIceCandidate, 
  sendVideoHangup,
  sendChatMessage
} from './websocket';

// WebRTC配置
const configuration = {
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    { urls: 'stun:stun1.l.google.com:19302' },
    { urls: 'stun:stun2.l.google.com:19302' },
  ]
};

// WebRTC连接对象
let peerConnection = null;
// 本地媒体流
let localStream = null;
// 远程媒体流
let remoteStream = null;
// 当前通话状态
let isCallInProgress = false;
// 当前用户ID
let currentUserId = null;
// 当前通话对象ID
let currentPeerId = null;
// 缓存的ICE候选者
let pendingIceCandidates = [];
// 事件处理器
let eventHandlers = {
  onCallStarted: null,
  onCallEnded: null,
  onIncomingCall: null,
  onLocalStream: null,
  onRemoteStream: null,
  onError: null,
  onScreenShare: null,
  onScreenShareEnded: null,
  onRemoteScreenShare: null
};

// 屏幕分享流
let screenShareStream = null;
let isScreenSharing = false;

// 初始化WebRTC
export const initWebRTC = (userId) => {
  currentUserId = userId;
  console.log('WebRTC初始化，用户ID:', userId);
};

// 设置事件处理器
export const setEventHandlers = (handlers) => {
  eventHandlers = { ...eventHandlers, ...handlers };
};

// 开始视频通话
export const startCall = async (peerId) => {
  try {
    if (isCallInProgress) {
      throw new Error('已有通话正在进行中');
    }
    
    // 确保之前的资源已经完全释放
    await cleanupCall();
    
    currentPeerId = peerId;
    
    // 创建RTCPeerConnection
    createPeerConnection();
    
    try {
      // 获取本地媒体流
      localStream = await navigator.mediaDevices.getUserMedia({ 
        video: true, 
        audio: true 
      });
    } catch (mediaError) {
      // 如果获取视频失败，尝试只获取音频
      if (mediaError.name === 'NotAllowedError' || mediaError.name === 'NotFoundError' || 
          mediaError.message.includes('Device in use')) {
        console.warn('无法获取视频，尝试只获取音频:', mediaError);
        try {
          localStream = await navigator.mediaDevices.getUserMedia({ 
            video: false, 
            audio: true 
          });
          alert('无法访问摄像头，将以纯音频模式进行通话。');
        } catch (audioError) {
          throw new Error('无法获取音频设备: ' + audioError.message);
        }
      } else {
        throw mediaError;
      }
    }
    
    // 将本地流添加到RTCPeerConnection
    localStream.getTracks().forEach(track => {
      peerConnection.addTrack(track, localStream);
    });
    
    // 触发本地流事件
    if (eventHandlers.onLocalStream) {
      eventHandlers.onLocalStream(localStream);
    }
    
    // 创建offer
    const offer = await peerConnection.createOffer();
    await peerConnection.setLocalDescription(offer);
    
    // 发送offer给对方
    const offerMessage = {
      sendUserId: currentUserId.toString(),
      receiveUserId: peerId.toString(),
      msgType: 'video-offer',
      sendText: JSON.stringify(offer)
    };
    
    sendVideoOffer(offerMessage);
    isCallInProgress = true;
    
    // 触发通话开始事件
    if (eventHandlers.onCallStarted) {
      eventHandlers.onCallStarted();
    }
    
    return true;
  } catch (error) {
    console.error('开始视频通话失败:', error);
    handleError(error);
    return false;
  }
};

// 接受视频通话
export const acceptCall = async (offer, peerId) => {
  try {
    if (isCallInProgress) {
      throw new Error('已有通话正在进行中');
    }
    
    // 确保之前的资源已经完全释放
    await cleanupCall();
    
    currentPeerId = peerId;
    
    // 创建RTCPeerConnection
    createPeerConnection();
    
    try {
      // 获取本地媒体流
      localStream = await navigator.mediaDevices.getUserMedia({ 
        video: true, 
        audio: true 
      });
    } catch (mediaError) {
      // 如果获取视频失败，尝试只获取音频
      if (mediaError.name === 'NotAllowedError' || mediaError.name === 'NotFoundError' || 
          mediaError.message.includes('Device in use')) {
        console.warn('无法获取视频，尝试只获取音频:', mediaError);
        try {
          localStream = await navigator.mediaDevices.getUserMedia({ 
            video: false, 
            audio: true 
          });
          alert('无法访问摄像头，将以纯音频模式进行通话。');
        } catch (audioError) {
          throw new Error('无法获取音频设备: ' + audioError.message);
        }
      } else {
        throw mediaError;
      }
    }
    
    // 将本地流添加到RTCPeerConnection
    localStream.getTracks().forEach(track => {
      peerConnection.addTrack(track, localStream);
    });
    
    // 触发本地流事件
    if (eventHandlers.onLocalStream) {
      eventHandlers.onLocalStream(localStream);
    }
    
    // 设置远程描述
    const offerDesc = JSON.parse(offer);
    await peerConnection.setRemoteDescription(new RTCSessionDescription(offerDesc));
    
    // 创建answer
    const answer = await peerConnection.createAnswer();
    await peerConnection.setLocalDescription(answer);
    
    // 发送answer给对方
    const answerMessage = {
      sendUserId: currentUserId.toString(),
      receiveUserId: peerId.toString(),
      msgType: 'video-answer',
      sendText: JSON.stringify(answer)
    };
    
    sendVideoAnswer(answerMessage);
    isCallInProgress = true;
    
    // 触发通话开始事件
    if (eventHandlers.onCallStarted) {
      eventHandlers.onCallStarted();
    }
    
    return true;
  } catch (error) {
    console.error('接受视频通话失败:', error);
    handleError(error);
    return false;
  }
};

// 处理视频通话应答
export const handleVideoAnswer = async (answer) => {
  try {
    if (!peerConnection) {
      throw new Error('没有活动的对等连接');
    }
    
    const answerDesc = JSON.parse(answer);
    await peerConnection.setRemoteDescription(new RTCSessionDescription(answerDesc));
    
    // 应用所有缓存的ICE候选者
    applyPendingIceCandidates();
  } catch (error) {
    console.error('处理视频通话应答失败:', error);
    handleError(error);
  }
};

// 处理ICE候选者
export const handleIceCandidate = async (candidate) => {
  try {
    if (!peerConnection) {
      console.log('暂无对等连接，缓存ICE候选者信息');
      pendingIceCandidates.push(candidate);
      return;
    }
    
    // 如果连接状态不是稳定的，也缓存ICE候选者
    if (peerConnection.signalingState !== 'stable') {
      console.log('连接状态不稳定，缓存ICE候选者信息');
      pendingIceCandidates.push(candidate);
      return;
    }
    
    const iceCandidate = JSON.parse(candidate);
    await peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidate));
  } catch (error) {
    console.error('处理ICE候选者失败:', error);
    // 这里不调用handleError，避免因为ICE候选者处理失败而结束通话
    console.warn('ICE候选者处理失败，但不影响通话继续');
  }
};

// 应用所有缓存的ICE候选者
const applyPendingIceCandidates = async () => {
  if (!peerConnection || pendingIceCandidates.length === 0) {
    return;
  }
  
  console.log(`应用${pendingIceCandidates.length}个缓存的ICE候选者`);
  
  // 创建一个副本并清空原数组
  const candidates = [...pendingIceCandidates];
  pendingIceCandidates = [];
  
  // 异步应用所有缓存的候选者
  setTimeout(async () => {
    for (const candidate of candidates) {
      try {
        const iceCandidate = JSON.parse(candidate);
        await peerConnection.addIceCandidate(new RTCIceCandidate(iceCandidate));
      } catch (error) {
        console.error('应用缓存的ICE候选者失败:', error);
      }
    }
  }, 1000); // 延迟1秒，确保连接已完全建立
};

// 结束视频通话
export const endCall = () => {
  try {
    if (!isCallInProgress) {
      return;
    }
    
    // 发送挂断消息
    if (currentPeerId) {
      const hangupMessage = {
        sendUserId: currentUserId.toString(),
        receiveUserId: currentPeerId.toString(),
        msgType: 'video-hangup',
        sendText: 'hangup'
      };
      
      sendVideoHangup(hangupMessage);
      
      // 发送视频通话结束的聊天消息
      const endCallMessage = {
        sendUserId: currentUserId.toString(),
        receiveUserId: currentPeerId.toString(),
        msgType: 'text',
        sendText: '视频通话已结束',
        sendTime: new Date().toISOString()
      };
      
      sendChatMessage(endCallMessage);
    }
    
    // 清理资源
    cleanupCall();
    
    return true;
  } catch (error) {
    console.error('结束视频通话失败:', error);
    handleError(error);
    return false;
  }
};

// 处理挂断视频通话
export const handleHangup = () => {
  cleanupCall();
};

// 创建对等连接
const createPeerConnection = () => {
  peerConnection = new RTCPeerConnection(configuration);
  
  // 监听ICE候选者事件
  peerConnection.onicecandidate = (event) => {
    if (event.candidate) {
      const candidateMessage = {
        sendUserId: currentUserId.toString(),
        receiveUserId: currentPeerId.toString(),
        msgType: 'ice-candidate',
        sendText: JSON.stringify(event.candidate)
      };
      
      sendIceCandidate(candidateMessage);
    }
  };
  
  // 监听连接状态变化
  peerConnection.onconnectionstatechange = (event) => {
    console.log('连接状态变化:', peerConnection.connectionState);
    if (peerConnection.connectionState === 'disconnected' || 
        peerConnection.connectionState === 'failed' || 
        peerConnection.connectionState === 'closed') {
      cleanupCall();
    }
  };
  
  // 监听信令状态变化
  peerConnection.onsignalingstatechange = () => {
    console.log('信令状态变化:', peerConnection.signalingState);
    if (peerConnection.signalingState === 'stable') {
      // 当信令状态稳定时，应用所有缓存的ICE候选者
      applyPendingIceCandidates();
    }
  };
  
  // 监听远程流
  peerConnection.ontrack = (event) => {
    if (!remoteStream) {
      remoteStream = new MediaStream();
      
      // 触发远程流事件
      if (eventHandlers.onRemoteStream) {
        eventHandlers.onRemoteStream(remoteStream);
      }
    }
    
    event.streams[0].getTracks().forEach(track => {
      remoteStream.addTrack(track);
    });
  };
};

// 清理通话资源
const cleanupCall = async () => {
  console.log('开始清理通话资源');
  
  // 停止屏幕分享
  if (isScreenSharing && screenShareStream) {
    try {
      screenShareStream.getTracks().forEach(track => {
        try {
          track.stop();
        } catch (e) {
          console.warn('停止屏幕分享轨道时出错:', e);
        }
      });
      screenShareStream = null;
      isScreenSharing = false;
    } catch (e) {
      console.warn('清理屏幕分享时出错:', e);
    }
  }
  
  // 关闭本地媒体流
  if (localStream) {
    try {
      localStream.getTracks().forEach(track => {
        try {
          track.stop();
          localStream.removeTrack(track);
        } catch (e) {
          console.warn('停止单个媒体流轨道时出错:', e);
        }
      });
    } catch (e) {
      console.warn('停止媒体流轨道时出错:', e);
    }
    localStream = null;
  }
  
  // 清空远程媒体流
  if (remoteStream) {
    try {
      remoteStream.getTracks().forEach(track => {
        try {
          track.stop();
          remoteStream.removeTrack(track);
        } catch (e) {
          console.warn('停止单个远程媒体流轨道时出错:', e);
        }
      });
    } catch (e) {
      console.warn('停止远程媒体流轨道时出错:', e);
    }
    remoteStream = null;
  }
  
  // 关闭对等连接
  if (peerConnection) {
    try {
      // 关闭所有发送器
      const senders = peerConnection.getSenders();
      if (senders && senders.length) {
        senders.forEach(sender => {
          if (sender.track) {
            try {
              sender.track.stop();
            } catch (e) {
              console.warn('停止发送器轨道时出错:', e);
            }
          }
        });
      }
      
      // 关闭所有接收器
      const receivers = peerConnection.getReceivers();
      if (receivers && receivers.length) {
        receivers.forEach(receiver => {
          if (receiver.track) {
            try {
              receiver.track.stop();
            } catch (e) {
              console.warn('停止接收器轨道时出错:', e);
            }
          }
        });
      }
      
      peerConnection.close();
    } catch (e) {
      console.warn('关闭对等连接时出错:', e);
    }
    peerConnection = null;
  }
  
  // 清空缓存的ICE候选者
  pendingIceCandidates = [];
  
  const wasCallInProgress = isCallInProgress;
  isCallInProgress = false;
  currentPeerId = null;
  
  // 触发通话结束事件，但只在之前确实有通话的情况下
  if (wasCallInProgress && eventHandlers.onCallEnded) {
    eventHandlers.onCallEnded();
  }
  
  console.log('通话资源清理完成');
  
  // 返回Promise以确保异步操作完成
  return new Promise(resolve => setTimeout(resolve, 500));
};

// 处理错误
const handleError = (error) => {
  console.error('WebRTC错误:', error);
  
  // 记录详细错误信息
  if (error.name) {
    console.error('错误类型:', error.name);
  }
  if (error.message) {
    console.error('错误消息:', error.message);
  }
  
  // 触发错误事件
  if (eventHandlers.onError) {
    eventHandlers.onError(error);
  }
  
  // 清理资源
  cleanupCall();
};

// 获取当前通话状态
export const getCallStatus = () => {
  return {
    isCallInProgress,
    currentPeerId
  };
};

// 开始分享屏幕
export const startScreenShare = async () => {
  if (isScreenSharing) {
    console.log('已经在分享屏幕');
    return;
  }
  
  if (!peerConnection || !isCallInProgress) {
    console.error('没有活动的通话，无法分享屏幕');
    return;
  }
  
  try {
    console.log('开始获取屏幕分享流');
    screenShareStream = await navigator.mediaDevices.getDisplayMedia({
      video: {
        cursor: 'always'
      },
      audio: false
    });
    
    // 保存原始视频轨道的状态
    const videoTrack = localStream.getVideoTracks()[0];
    const videoEnabled = videoTrack ? videoTrack.enabled : false;
    
    // 替换视频轨道
    const screenTrack = screenShareStream.getVideoTracks()[0];
    
    // 获取发送器
    const senders = peerConnection.getSenders();
    const videoSender = senders.find(sender => 
      sender.track && sender.track.kind === 'video'
    );
    
    if (videoSender) {
      console.log('替换视频轨道为屏幕分享');
      await videoSender.replaceTrack(screenTrack);
      
      // 重新协商连接，确保对方能看到屏幕分享
      const offer = await peerConnection.createOffer();
      await peerConnection.setLocalDescription(offer);
      
      // 发送新的offer给对方
      const offerMessage = {
        sendUserId: currentUserId.toString(),
        receiveUserId: currentPeerId.toString(),
        msgType: 'video-offer',
        sendText: JSON.stringify(offer)
      };
      
      sendVideoOffer(offerMessage);
      
      // 不发送屏幕分享开始消息，直接通过视频信令通知对方
    } else {
      console.log('添加屏幕分享轨道');
      peerConnection.addTrack(screenTrack, screenShareStream);
      
      // 重新协商连接
      const offer = await peerConnection.createOffer();
      await peerConnection.setLocalDescription(offer);
      
      // 发送新的offer给对方
      const offerMessage = {
        sendUserId: currentUserId.toString(),
        receiveUserId: currentPeerId.toString(),
        msgType: 'video-offer',
        sendText: JSON.stringify(offer)
      };
      
      sendVideoOffer(offerMessage);
    }
    
    isScreenSharing = true;
    
    // 监听屏幕分享结束事件
    screenTrack.addEventListener('ended', () => {
      stopScreenShare(videoEnabled);
    });
    
    // 触发屏幕分享开始事件
    if (eventHandlers.onScreenShare) {
      eventHandlers.onScreenShare(screenShareStream);
    }
    
    console.log('屏幕分享开始成功');
    return true;
  } catch (error) {
    console.error('分享屏幕时出错:', error);
    if (eventHandlers.onError) {
      eventHandlers.onError(error);
    }
    return false;
  }
};

// 停止分享屏幕
export const stopScreenShare = async (restoreVideo = true) => {
  if (!isScreenSharing || !screenShareStream) {
    console.log('没有活动的屏幕分享');
    return;
  }
  
  try {
    console.log('停止屏幕分享');
    
    // 停止所有屏幕分享轨道
    screenShareStream.getTracks().forEach(track => {
      track.stop();
    });
    
    // 如果有活动的通话，恢复摄像头视频
    if (peerConnection && isCallInProgress && localStream) {
      const senders = peerConnection.getSenders();
      const videoSender = senders.find(sender => 
        sender.track && sender.track.kind === 'video'
      );
      
      if (videoSender && restoreVideo) {
        const videoTrack = localStream.getVideoTracks()[0];
        if (videoTrack) {
          console.log('恢复摄像头视频');
          await videoSender.replaceTrack(videoTrack);
          videoTrack.enabled = true;
          
          // 重新协商连接，确保对方能看到摄像头视频
          const offer = await peerConnection.createOffer();
          await peerConnection.setLocalDescription(offer);
          
          // 发送新的offer给对方
          const offerMessage = {
            sendUserId: currentUserId.toString(),
            receiveUserId: currentPeerId.toString(),
            msgType: 'video-offer',
            sendText: JSON.stringify(offer)
          };
          
          sendVideoOffer(offerMessage);
        }
      }
    }
    
    screenShareStream = null;
    isScreenSharing = false;
    
    // 触发屏幕分享结束事件
    if (eventHandlers.onScreenShareEnded) {
      eventHandlers.onScreenShareEnded();
    }
    
    console.log('屏幕分享已停止');
    return true;
  } catch (error) {
    console.error('停止屏幕分享时出错:', error);
    if (eventHandlers.onError) {
      eventHandlers.onError(error);
    }
    return false;
  }
};

// 获取屏幕分享状态
export const getScreenShareStatus = () => {
  return {
    isScreenSharing,
    screenShareStream
  };
};

// 处理屏幕分享状态消息
export const handleScreenShareStatus = (isSharing) => {
  if (eventHandlers.onRemoteScreenShare) {
    eventHandlers.onRemoteScreenShare(isSharing);
  }
}; 